package com.ourteam.frame.web;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.reflect.MethodUtils;

import net.dao.BaseQueryBean;
import net.dao.IDataAccessInterface;
import net.service.SpringContextAgent;

public class DataAccessHelper<D,T extends BaseQueryBean, S extends AbstractSearchModel<T>>
		extends AbstractSearchHelper<T, S> {

	private IDataAccessInterface<D, T> dataAccessObject;

	private String queryBeanClassName;

	private String dataObjectClassName;

	public DataAccessHelper(Class<? extends IDataAccessInterface<D, T>> daoClass) {
		dataAccessObject = SpringContextAgent.getBean(daoClass);

		queryBeanClassName = daoClass.getPackage().getName() + "."
				+ StringUtils.substringBetween(daoClass.getName(), "I", "DAO") + "DAOQueryBean";

		dataObjectClassName = daoClass.getPackage().getName() + "."
				+ StringUtils.substringBetween(daoClass.getName(), "I", "DAO");
	}

	public DataAccessHelper(S searchModel, Class<? extends IDataAccessInterface<D, T>> daoClass) {
		super(searchModel);

		dataAccessObject = SpringContextAgent.getBean(daoClass);

		queryBeanClassName = daoClass.getPackage().getName() + "."
				+ StringUtils.substringBetween(daoClass.getName(), "I", "DAO") + "DAOQueryBean";

		dataObjectClassName = daoClass.getPackage().getName() + "."
				+ StringUtils.substringBetween(daoClass.getName(), "I", "DAO");

	}

	@Override
	protected int queryCount(T queryBean) throws Exception {
		return dataAccessObject.queryCount(queryBean);
	}

	@Override
	protected Object[] queryData(T queryBean) throws Exception {
		return dataAccessObject.querySelective(queryBean);
	}

	public void addNew(D dataObject) throws Exception {
		MethodUtils.invokeMethod(dataAccessObject, "insert", new Object[] { dataObject },
				new Class[] { Class.forName(dataObjectClassName) });
	}

	public void modify(D dataObject) throws Exception {

		MethodUtils.invokeMethod(dataAccessObject, "update", new Object[] { dataObject },
				new Class[] { Class.forName(dataObjectClassName) });
	}

	public void modify(D dataObject, T queryBean) throws Exception {
		MethodUtils.invokeMethod(dataAccessObject, "update", new Object[] { dataObject, queryBean },
				new Class[] { Class.forName(dataObjectClassName), queryBean.getClass() });
	}

	public void delete(D dataObject) throws Exception {
		MethodUtils.invokeMethod(dataAccessObject, "delete", new Object[] { dataObject },
				new Class[] { Class.forName(dataObjectClassName) });
	}

	public void delete(D dataObject, T queryBean) throws Exception {
		MethodUtils.invokeMethod(dataAccessObject, "delete", new Object[] { dataObject, queryBean },
				new Class[] { Class.forName(dataObjectClassName), queryBean.getClass() });
	}

	public D newDataObject() {
		try {
			return (D)Class.forName(dataObjectClassName).newInstance();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	protected T createQueryBean() {
		try {
			return (T) Class.forName(queryBeanClassName).newInstance();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

}
